home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_3.5 / bcd / edge / hyst.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  4.7 KB  |  209 lines

  1. /*
  2.  * (c) Copyright 1988 by
  3.  * Robotics Principles Research Department, AT&T Bell Laboratories.
  4.  * All rights reserved.
  5.  * Last modified 2/8/88 Ingemar J. Cox
  6.  * C version 8/2/88 Deborah A. Wallach
  7.  * C version 11/4/88 W. K. Kropfl
  8.  */
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include "edge_finder.h"
  12.  
  13. extern struct image *my_image;
  14. void image_neighbor_fwd();
  15. void image_neighbor_bwd();
  16.  
  17. static nx, ny;
  18. int  nxXny;
  19.  
  20. unsigned char* image_hysteresis(lo_thld)
  21.      int lo_thld;
  22. {
  23.     register int iy, ix;
  24.     register unsigned char *lmapP, *lmap_hiP, *mapP;
  25.     
  26.     nx = my_image->nx;
  27.     ny = my_image->ny;
  28.     nxXny = nx*ny;
  29.     my_image->lo_threshold = lo_thld;
  30.     my_image->edge_map_hi = my_image->edge_map;
  31.     my_image->edge_map = (unsigned char *)malloc(nx*ny*sizeof(unsigned char));
  32.  
  33.     lmap_hiP = &my_image->edge_map_hi[0];
  34.     lmapP    = &my_image->edge_map[0];
  35.  
  36.     mapP = lmapP;
  37.     for(ix=nx*ny; --ix>=0; )
  38.         *mapP++ = 0;
  39.  
  40.     for(iy=0; iy<ny; iy++, lmap_hiP+=nx, lmapP+=nx)
  41.     {
  42.         mapP = lmapP;
  43.         for(ix=0; ix<nx; ix++, mapP++)
  44.         {
  45.             if(lmap_hiP[ix] != 0)
  46.             {
  47.                 *mapP = lmap_hiP[ix];
  48.                 image_neighbor_fwd(iy, ix, mapP);
  49.                 image_neighbor_bwd(iy, ix, mapP);
  50.             }
  51.         }
  52.     }
  53.     return(my_image->edge_map);
  54. }
  55.  
  56. void image_neighbor_fwd(iy, ix, mapP)
  57. register int iy, ix;
  58. register unsigned char *mapP;
  59. {
  60.     switch(*mapP)
  61.     {
  62.         case 5:
  63.             return;
  64.  
  65.         case EDGE_Y: /*0*/
  66.             if(!Fcontour(iy,ix+1)&&Fcontour(iy,ix+2))
  67.                 goto L_EDGE_Y;
  68.             else if(!(Fcontour(iy-1,ix+1)||Fcontour(iy+1,ix+1))&&
  69.                 (Fcontour(iy-1,ix+2)||Fcontour(iy+1,ix+2)))
  70.             {
  71.     L_EDGE_Y:        if(ix+1<nx) *(mapP+1) = 5;
  72.             }
  73.             break;
  74.         case EDGE_135: /*45*/
  75.             if(!Fcontour(iy-1,ix+1)&&Fcontour(iy-2,ix+2))
  76.                 goto L_EDGE_135;
  77.             else if(!(Fcontour(iy,ix+1)||Fcontour(iy-1,ix))&&
  78.                 (Fcontour(iy-2,ix+1)||Fcontour(iy-1, ix+2)))
  79.             {
  80.     L_EDGE_135:        if((iy-1>=0)&&(ix+1<nx)) *(mapP-nx+1) = 5;
  81.             }
  82.             break;
  83.         case EDGE_X: /*90*/
  84.             if(!Fcontour(iy-1, ix)&&Fcontour(iy-2, ix))
  85.                 goto L_EDGE_X;
  86.             else if(!(Fcontour(iy-1, ix-1)||Fcontour(iy-1, ix+1))&&
  87.                 (Fcontour(iy-2, ix-1)||Fcontour(iy-2,ix+1)))
  88.             {
  89.     L_EDGE_X:        if(iy-1>=0) *(mapP-nx) = 5;
  90.             }
  91.             break;
  92.         case EDGE_45: /*135*/
  93.             if(!Fcontour(iy+1, ix+1)&&Fcontour(iy+2,ix+2))
  94.                 goto L_EDGE_45;
  95.             else if(!(Fcontour(iy,ix+1)||Fcontour(iy+1,ix))&&
  96.                 (Fcontour(iy+1,ix+2)||Fcontour(iy+2,ix+1)))
  97.             {
  98.     L_EDGE_45:        if((iy+1<ny)&&(ix+1<nx)) *(mapP+nx+1) = 5;
  99.             }
  100.             break;
  101.         default:
  102.             fprintf(stderr, "error in case statements\n");
  103.             fprintf(stderr, "x=%d y=%d\n",ix, iy);
  104.             exit(1);
  105.             break;
  106.     }
  107. }
  108.  
  109. void image_neighbor_bwd(iy, ix, mapP)
  110. register int iy, ix;
  111. register unsigned char *mapP;
  112. {
  113.     switch(*mapP)
  114.     {
  115.         case  5:
  116.             return;
  117.  
  118.         case EDGE_Y: /*0*/
  119.             if(!Bcontour(iy,ix-1)&&Bcontour(iy,ix-2))
  120.                 goto L_EDGE_Y;
  121.             else if(!(Bcontour(iy-1,ix-1)||Bcontour(iy+1,ix-1))&&
  122.                 (Bcontour(iy-1,ix-2)||Bcontour(iy+1,ix-2)))
  123.             {
  124.     L_EDGE_Y:        if(ix-1>=0) *(mapP-1) = 5;
  125.             }
  126.             break;
  127.         case EDGE_135: /*45*/
  128.             if(!Bcontour(iy+1,ix-1)&&Bcontour(iy+2,ix-2))
  129.                 goto L_EDGE_135;
  130.             else if(!(Bcontour(iy,ix-1)||Bcontour(iy+1,ix))&&
  131.                 (Bcontour(iy+1,ix-2)||Bcontour(iy+2,ix-1)))
  132.             {
  133.     L_EDGE_135:        if((iy+1<ny)&&(ix-1>=0)) *(mapP+nx-1) = 5;
  134.             }
  135.             break;
  136.         case EDGE_X: /*90*/
  137.             if(!Bcontour(iy+1, ix)&&Bcontour(iy+2, ix))
  138.                 goto L_EDGE_X;
  139.             else if(!(Bcontour(iy+1,ix-1)||Bcontour(iy+1,ix+1))&&
  140.                 (Bcontour(iy+2,ix-1)||Bcontour(iy+2,ix+1)))
  141.             {
  142.     L_EDGE_X:        if(iy+1<ny) *(mapP+nx) = 5;
  143.             }
  144.             break;
  145.         case EDGE_45: /*135*/
  146.             if(!Bcontour(iy-1, ix-1)&&Bcontour(iy-2,ix-2))
  147.                 goto L_EDGE_45;
  148.             else if(!(Bcontour(iy,ix-1)||Bcontour(iy-1,ix))&&
  149.                 (Bcontour(iy-1,ix-2)||Bcontour(iy-2,ix-1)))
  150.             {
  151.     L_EDGE_45:        if((iy-1>=0)&&(ix-1>=0)) *(mapP-nx-1) = 5;
  152.             }
  153.             break;
  154.         default:
  155.             fprintf(stderr, "error in case statements\n");
  156.             fprintf(stderr, "x=%d y=%d\n",ix, iy);
  157.             exit(1);
  158.             break;
  159.     }
  160. }
  161.  
  162. int Fcontour(iy, ix)
  163. register int iy, ix;
  164. {
  165.     int edge_pt, index;
  166.     register unsigned char *mapP;
  167.  
  168.     /*if(ix<0||ix>=nx||iy<0||iy>=ny) return(0);*/
  169.  
  170.     index =iy*nx+ix;
  171.     if(index<0 || index>=nxXny)
  172.         return(0);
  173.  
  174.     mapP = &my_image->edge_map[index];
  175.     if(*mapP > 0)
  176.         return(1);
  177.     else if((edge_pt=image_edge_map_lo(ix, iy, index)) != 0)
  178.     {
  179.         *mapP = edge_pt;
  180.         image_neighbor_fwd(iy, ix, mapP);
  181.         return(1);
  182.     } else
  183.         return(0);
  184. }
  185.  
  186. int Bcontour(iy, ix)
  187. register int iy, ix;
  188. {
  189.     register unsigned char *mapP;
  190.     int edge_pt, index;
  191.  
  192.     /*if(ix<0||ix>=nx||iy<0||iy>=ny) return(0);*/
  193.  
  194.     index =iy*nx+ix;
  195.     if(index<0 || index>=nxXny)
  196.         return(0);
  197.  
  198.     mapP = &my_image->edge_map[index];
  199.     if(*mapP > 0)
  200.         return(1);
  201.     else if((edge_pt=image_edge_map_lo(ix, iy, index)) != 0)
  202.     {
  203.         *mapP = edge_pt;
  204.         image_neighbor_bwd(iy, ix, mapP);
  205.         return(1);
  206.     } else
  207.         return(0);
  208. }
  209.